package com.orangelife.controller;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang.time.StopWatch;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.orangelife.common.AbstractV2TransferService;
import com.orangelife.exception.AppBizException;
import com.orangelife.exception.AppPopException;
import com.orangelife.service.base.common.GeneralJsonEntity;
import com.orangelife.session.SessionManager;
import com.orangelife.setting.constant.CodeConst;
import com.orangelife.setting.constant.ContextConst;
import com.orangelife.setting.constant.InfoConst;
import com.orangelife.webservice.base.HeaderConst;

@Aspect
@Component
public class WxtOnlineController extends AbstractV2TransferService {

	@Resource(name = "sessionManager")
	private SessionManager sessionManager;

	// 用户超时、权限验证
	@Pointcut("@annotation(com.orangelife.controller.AuthPermission)")
	public void accessControlPointCut() {
	}

	@Pointcut("execution(* com.orangelife.webService.*.*.*.*(..))")
	public void dhxtServicePointCut() {
	}

	@Pointcut("execution(* com.orangelife.webservice..*.*(..))")
	public void webPointCut() {
	}

	// 用户超时、权限验证
	@Pointcut("@annotation(com.orangelife.controller.AuthPermission)")
	public void onlineControlPointCut() {
	}

	/**
	 * Session 控制处理
	 * 
	 * @param jp
	 * @return
	 * @throws Throwable
	 */
	@Around("accessControlPointCut()")
	public Object doWhenNeedAccessControl(ProceedingJoinPoint jp)
			throws Throwable {
		logger.debug("need an session access control!");
		Object[] args = jp.getArgs();
		if (args == null || args.length <= 0) {
			throw new IllegalArgumentException(
					"argument list should start with HttpServletRequest & HttpServletResponse at least!");
		}
		HttpServletRequest request = null;
		if (!(args[0] instanceof HttpServletRequest)) {
			throw new IllegalArgumentException(
					"args[0] should be HttpServletRequest!");
		}
		request = (HttpServletRequest) args[0];
		if (request == null) {
			throw new IllegalArgumentException("request should not be null!");
		}

		String sessionId = request.getHeader(HeaderConst.ACCESS_TOKEN);
		if (sessionId == null) {
			logger.info("sessionId not found in header:" + sessionId);
			return responseBySystemErr(1011, "请您先登陆");
		}
		logger.debug("reached a sessionId:" + sessionId);
		if (sessionManager.getSession(sessionId) == null) {
			logger.info("session not found:" + sessionId);
			return responseBySystemErr(1011, "请您先登陆");
		}

		try {
			return jp.proceed(jp.getArgs());
			
			
			
		} catch (AppBizException abe) {
			return responseBySystemErr(abe.getCode(), abe.getMessage());
		} catch (Exception e) {
			logger.error(e.getMessage());
			System.out.println(e.getMessage());
			return responseBySystemErr(000001, "亲，服务器小生魂游太空了");
		}
	}

	private Response responseBySystemErr(Integer code, String message)
			throws IOException {
		ResponseBuilder rb = Response.status(HttpStatus.SC_OK);
		GeneralJsonEntity entity = new GeneralJsonEntity();
		entity.setErrCode(code);
		entity.setErrInfo(message);
		rb.entity(entity);
		return rb.build();
	}

	/**
	 * 交易处理
	 * 
	 * @param pjp
	 * @return
	 * @throws Throwable
	 */
	@Around("dhxtServicePointCut()")
	public Object processDhxtService(ProceedingJoinPoint pjp) throws Throwable {
		StopWatch clock = new StopWatch();
		clock.start(); // 计时开始

		try {
			Object object = pjp.proceed();
			clock.stop(); // 计时结束
			logger.info("execution time:{} ms", clock.getTime());
			return object;
		} catch (AppBizException e) {
			logger.error(String.format("%d:%s", e.getCode(), e.getMessage()));
			// return this.abnormalResp(e.getCode(), e.getMessage());
			return this.abnormalResp(CodeConst.BUSINESS, e.getMessage());
		} catch (AppPopException e) {
			logger.error(String.format("%d:%s", e.getCode(), e.getMessage()));
			return this.abnormalResp(CodeConst.BUSINESS, e.getMessage());
		} catch (Exception e) {
			logger.error(InfoConst.ABNORMAL, e);
			return this.abnormalResp(CodeConst.ABNORMAL, InfoConst.ABNORMAL);
		}
	}

	/**
	 * 交易处理
	 * 
	 * @param pjp
	 * @return
	 * @throws Throwable
	 */
	@Around("webPointCut()")
	public Object webDhxtService(ProceedingJoinPoint pjp) throws Throwable {
		StopWatch clock = new StopWatch();
		clock.start(); // 计时开始

		try {
			Object object = pjp.proceed();
			clock.stop(); // 计时结束
			logger.info("execution time:{} ms", clock.getTime());
			return object;
		} catch (AppBizException e) {
			logger.error(String.format("%d:%s", e.getCode(), e.getMessage()));
			// return this.abnormalResp(e.getCode(), e.getMessage());
			return this.abnormalResp(CodeConst.BUSINESS, e.getMessage());
		} catch (AppPopException e) {
			logger.error(String.format("%d:%s", e.getCode(), e.getMessage()));
			return this.abnormalResp(CodeConst.BUSINESS, e.getMessage());
		} catch (Exception e) {
			logger.error(InfoConst.ABNORMAL, e);
			return this.abnormalResp(CodeConst.ABNORMAL, InfoConst.ABNORMAL);
		}
	}

	/**
	 * Session 控制处理
	 * 
	 * @param jp
	 * @return
	 * @throws Throwable
	 */
	@Around("onlineControlPointCut()")
	public Object doWhenNeedOnlineControl(ProceedingJoinPoint jp)
			throws Throwable {
		Object[] args = jp.getArgs();
		if (args == null || args.length <= 0) {
			throw new IllegalArgumentException(
					"argument list should start with HttpServletRequest & HttpServletResponse at least!");
		}
		HttpServletRequest request = null;
		if (!(args[0] instanceof HttpServletRequest)) {
			throw new IllegalArgumentException(
					"args[0] should be HttpServletRequest!");
		}
		request = (HttpServletRequest) args[0];
		if (request == null) {
			throw new IllegalArgumentException("request should not be null!");
		}

		String sessionId = request.getHeader(ContextConst.ACCESS_TOKEN);
		if (sessionId == null) {
			logger.info("sessionId not found in header:" + sessionId);
			return this.abnormalResp(CodeConst.SYS_CODE_2001,
					InfoConst.SYS_INFO_2001);
		}

		if (sessionManager.getSession(sessionId) == null) {
			logger.info("session not found:" + sessionId);
			return this.abnormalResp(CodeConst.SYS_CODE_2001,
					InfoConst.SYS_INFO_2001);
		}

		/* 触发切入点方法执行 */
		return jp.proceed(jp.getArgs());
	}

}
